﻿using System;
using System.Drawing;
using System.Windows.Forms;

using Moe.ECamel.Client.Controllers;
using Moe.ECamel.Client.WinForms.Common;
using Moe.ECamel.Client.WinForms.Forms;
using Moe.ECamel.Common.Entities;

namespace Moe.ECamel.Client.WinForms.Controls
{
	public partial class LibraryTreeControl : ECamelUserControl
	{
		private readonly LibrariesController _controller;

		public LibraryTreeControl()
		{
			InitializeComponent();
		}

		public LibraryTreeControl(LibrariesController controller)
			:this()
		{
			this._controller = controller;
			this._controller.LibraryUpdated += Controller_LibraryUpdated;
			this.RefreshLibrariesList();
		}

		private void Controller_LibraryUpdated(object sender, LibraryEventArgs e)
		{
			var library = GetCurrentLibrary();
			if (library.LibraryId == e.Library.LibraryId)
			{
				library = e.Library;
				RefreshTreeNodeFont(LibrariesTreeView.SelectedNode, library);
				RefreshCurrentLibrary(library);				
			}
		}

		private void RefreshLibrariesList()
		{
			// Refresh libraries list:
			this._controller.RefreshList();
			// Clear previous nodes, if any:
			this.LibrariesTreeView.Nodes.Clear();
			// Generate library tree:
			var rootTreeNode = new TreeNode("רשת ספריות ארצית");
			foreach (var library in _controller.List.FindAll(l => l.ParentLibraryId == null))
				GenerateLibraryNode(library, rootTreeNode);
			this.LibrariesTreeView.Nodes.Add(rootTreeNode);
			this.LibrariesTreeView.ExpandAll();
			this.LibrariesTreeView.SelectedNode = rootTreeNode;
			RefreshCurrentLibrary(null);
		}

		private void GenerateLibraryNode(Library library, TreeNode parentLibraryNode)
		{
			// Create a tree node for this library:
			var libraryNode = new TreeNode();
			RefreshTreeNodeFont(libraryNode, library);
			// Generate direct children recursively:
			foreach (var childLibrary in _controller.List.FindAll(l => l.ParentLibraryId == library.LibraryId))
				GenerateLibraryNode(childLibrary, libraryNode);
			// Add this library to the parent tree node:
			parentLibraryNode.Nodes.Add(libraryNode);
		}

		private void RefreshCurrentLibrary(Library library)
		{
			if (CurrentLibraryControl != null)
			{
				splitContainer1.Panel2.Controls.Remove(CurrentLibraryControl);
				CurrentLibraryControl.Dispose();
				CurrentLibraryControl = null;
			}

			if (library != null)
			{
				var detailsController = new EntityDetailsController<Library>(DetailsMode.View, library, _controller);
				CurrentLibraryControl = new LibraryControl(detailsController);
				splitContainer1.Panel2.Controls.Add(CurrentLibraryControl);
				CurrentLibraryControl.Dock = DockStyle.Fill;
			}

			RefreshMenus();
		}

		private void RefreshMenus()
		{
			var library = GetCurrentLibrary();
			this.AddToolStripMenuItem.Enabled = this.AddMenuItem.Enabled =  library == null || 
				library.LibraryTypeId < ECamelHelper.LibraryTypes.Count;
			this.ChangeStatusToolStripMenuItem.Enabled = this.ChangeStatusMenuItem.Enabled =  library != null;
		}

		private Library GetCurrentLibrary()
		{
			return (Library)LibrariesTreeView.SelectedNode.Tag;			
		}

		private void AddLibrary()
		{
			var currentLibrary = GetCurrentLibrary();
			var newLibrary = _controller.NewLibrary(currentLibrary);
			EntityDetailsController<Library> detailsProvider = new EntityDetailsController<Library>(DetailsMode.Create, newLibrary, _controller);
			using (var dialog = new LibraryDetailsForm(detailsProvider))
			{
				var dialogResult = dialog.ShowDialog();
				if (dialogResult == DialogResult.OK)
					RefreshLibrariesList();
			}
		}
		private void ChangeLibraryStatus()
		{
			var library = GetCurrentLibrary();
			if (library == null)
				return;
			var error = _controller.UpdateLibraryStatus(library, !library.Active);
			if (error != null)
				ECamelHelper.ShowMessage(error);
			else
			{
			}
		}

		private void LibrariesTreeView_AfterSelect(object sender, TreeViewEventArgs e)
		{
			RefreshCurrentLibrary((Library)e.Node.Tag);
		}

		private void RefreshTreeNodeFont(TreeNode treeNode, Library library)
		{
			treeNode.Tag = library;
			treeNode.Text = library.LibraryName;
			treeNode.NodeFont = library.Active ? null : new Font(LibrariesTreeView.Font, FontStyle.Strikeout);
		}

		private void AddToolStripMenuItem_Click(object sender, EventArgs e)
		{
			AddLibrary();
		}
		private void ChangeStatusToolStripMenuItem_Click(object sender, EventArgs e)
		{
			ChangeLibraryStatus();
		}

		private void AddMenuItem_Click(object sender, EventArgs e)
		{
			AddLibrary();
		}
		private void ChangeStatusMenuItem_Click(object sender, EventArgs e)
		{
			ChangeLibraryStatus();
		}
	}
}
